#include <iostream>
#include <vector>
#include <iomanip>
#include "hr_time.h"
#include "map_ip.h"
#include "bounded_vector.h"
#include "char_counter.h"

using namespace std;

namespace U31
{
	int rec_fak(int i)
	{
		if (i <= 1)
			return 1;
		else
			return i * rec_fak(i - 1);
	}

	int rec_pow(int x, int i)
	{
		if (i <= 0)
			return 1;
		else
			return x * rec_pow(x, i - 1);
	}

	int it_fak(int i)
	{
		int res = 1;
		for (int n = 2; n <= i; n++)
		{
			res *= n;
		}
		return res;
	}

	int it_pow(int x, int i)
	{
		int res = 1;
		for (int n = 0; n < i; n++)
		{
			res *= x;
		}
		return res;
	}

	int recursive(int x, int i)
	{
		return rec_pow(x, i) / rec_fak(i);
	}

	int iterative(int x, int i)
	{
		return it_pow(x, i) / it_fak(i);
	}

}

void main3_1()
{
	cout << "Main3_1" << endl;
	using namespace U31;
	//for (int i = 0; i < 5; i++)
	//{
	//	for (int j = 0; j < 5; j++)
	//	{
	//		cout << recursive(i, j) << " : " << iterative(i, j) << endl;
	//	}
	//}

	if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == 0)
	{
		std::cout << "Error: SetPriorityClass: " << GetLastError() << endl;
	}
	if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) == 0)
	{
		std::cout << "Error: SetThreadPriority" << endl;
	}

	struct Meassurement
	{
		int x;
		int i;
		double time;
	};

	int nloops = 1000;
	vector<Meassurement> rec_times;
	vector<Meassurement> it_times;
	CStopWatch w;
	cout.precision(8);

	for (volatile int x = 0; x < 5; x++)
	{
		for (volatile int i = 0; i < 3; i++)
		{
			w.startTimer();
			for (volatile int n = 0; n < nloops; n++)
			{
				;
			}
			w.stopTimer();
			double tloop = 1e6*w.getElapsedTime();

			w.startTimer();
			for (volatile int n = 0; n < nloops; n++)
			{
				volatile int rec = recursive(x, i);
			}
			w.stopTimer();
			Meassurement m1 = {x, i, ((1e6*w.getElapsedTime() - tloop) / (double)nloops) };
			rec_times.push_back(m1);

			w.startTimer();
			for (volatile int n = 0; n < nloops; n++)
			{
				volatile int iter = iterative(x, i);
			}
			w.stopTimer();

			Meassurement m2 = { x, i, ((1e6*w.getElapsedTime() - tloop) / (double)nloops) };
			it_times.push_back(m2);
		}
	}
	for (int i = 0; i < rec_times.size(); i++)
	{
		cout << "x: " << rec_times[i].x << " i: " << rec_times[i].i << " rec time: " << rec_times[i].time;
		cout << " it time: " << it_times[i].time << endl;
	}

}

void main3_2()
{
	cout << "Main3_2" << endl;
	using namespace U32;
	map_ip ip;
	ip.read_from_file("ip_one.txt");
	cout << ip.num_connections("151.105.179.139") << endl;
	ip.print_max_connected();
}

void main4_1()
{
	cout << "Main4_1" << endl;
	bounded_vector bv1('a', 'c');
	bv1['a'] = 1;
	bv1['b'] = 1;
	bv1['c'] = 1;
	bounded_vector bv2('a', 'c');
	bv2['a'] = 2;
	bv2['b'] = 2;
	bv2['c'] = 2;

	bounded_vector bv3; 
	bv3 = bv1 + bv2;
}

void main4_3()
{
	cout << "Main4_2" << endl;
	char_counter cc;
	cc.read_files("char1.txt", "char2.txt");
	cc.print();
}

int main()
{
	//main3_1();
	//main3_2();
	//main4_1();
	main4_3();

	system("pause");
	return 0;
}